﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Controls;
using System.Diagnostics;
using System.Windows.Navigation;
using System.Windows.Media.Animation;
using System.Windows;
using System.Windows.Threading;
using System.Threading;

namespace MyCalManager.Helper
{

    public class FaderFrame : Frame
    {
        #region DependencyPropertys

        public static readonly DependencyProperty TransitionTypeProperty = DependencyProperty.Register("TransitionType",
            typeof(PageTransitionType),
            typeof(FaderFrame), new PropertyMetadata(PageTransitionType.SlideAndFade));

        public PageTransitionType TransitionType
        {
            get
            {
                return (PageTransitionType)GetValue(TransitionTypeProperty);
            }
            set
            {
                SetValue(TransitionTypeProperty, value);
            }
        }


        #endregion

        public FaderFrame()
            : base()
        {
            // watch for navigations
            Navigating += OnNavigating;
        }

        public override void OnApplyTemplate()
        {
            // get a reference to the frame's content presenter
            // this is the element we will fade in and out
            _contentPresenter = GetTemplateChild("PART_FrameCP") as ContentPresenter;
            base.OnApplyTemplate();
        }

        protected void OnNavigating(object sender, NavigatingCancelEventArgs e)
        {
            // if we did not internally initiate the navigation:
            //   1. cancel the navigation,
            //   2. cache the target,
            //   3. disable hittesting during the fade, and
            //   4. fade out the current content
            if (Content != null && !_allowDirectNavigation && _contentPresenter != null)
            {
                e.Cancel = true;
                _navArgs = e;
                _contentPresenter.IsHitTestVisible = false;
                string story = string.Format("{0}Out", TransitionType.ToString());
                Storyboard ta = (Storyboard)FindResource(story);
                ta.Completed += StoryCompleted;
                //Page c = (Page)_contentPresenter.Content;
                
                //var g = c.Content;
                _contentPresenter.BeginStoryboard(ta);
            }
            _allowDirectNavigation = false;
        }

        private void StoryCompleted(object sender, EventArgs e)
        {
            // after the fade out
            //   1. re-enable hittesting
            //   2. initiate the delayed navigation
            //   3. invoke the FadeIn animation at Loaded priority
            (sender as ClockGroup).Completed -= StoryCompleted;
            if (_contentPresenter != null)
            {
                _contentPresenter.IsHitTestVisible = true;

                _allowDirectNavigation = true;
                switch (_navArgs.NavigationMode)
                {
                    case NavigationMode.New:
                        if (_navArgs.Uri == null)
                        {
                            NavigationService.Navigate(_navArgs.Content);
                        }
                        else
                        {
                            NavigationService.Navigate(_navArgs.Uri);
                        }
                        break;

                    case NavigationMode.Back:
                        NavigationService.GoBack();
                        break;

                    case NavigationMode.Forward:
                        NavigationService.GoForward();
                        break;

                    case NavigationMode.Refresh:
                        NavigationService.Refresh();
                        break;
                }

                Dispatcher.BeginInvoke(DispatcherPriority.Loaded,
                    (ThreadStart)delegate()
                    {
                        string story = string.Format("{0}In", TransitionType.ToString());
                        Storyboard ta = (Storyboard)FindResource(story);
                        _contentPresenter.BeginStoryboard(ta);
                    });
            }
        }

        private bool _allowDirectNavigation = false;
        private ContentPresenter _contentPresenter = null;
        private NavigatingCancelEventArgs _navArgs = null;
    }

}
